home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 79 / maccd 79.iso / multimedial / GL Tron / Source / gltron / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-10  |  6.2 KB  |  260 lines  |  [TEXT/CWIE]

  1. #include "gltron.h"
  2.  
  3. int processEvent(GameEvent* e) {
  4.   int value = 0;
  5.   Data *data;
  6.  
  7.   if(game2->mode == GAME_SINGLE_RECORD) {
  8.     writeEvent(e);
  9.   }
  10.   switch(e->type) {
  11.   case EVENT_TURN_LEFT:
  12.     data = game->player[e->player].data;
  13.     if(data->speed > 0) {
  14.       data->iposx = e->x;
  15.       data->iposy = e->y;
  16.       data->turn = TURN_LEFT;
  17.       doTurn(data, e->timestamp);
  18.     }
  19.     break;
  20.   case EVENT_TURN_RIGHT:
  21.     data = game->player[e->player].data;
  22.     if(data->speed > 0) {
  23.       data->iposx = e->x;
  24.       data->iposy = e->y;
  25.       data->turn = TURN_RIGHT;
  26.       doTurn(data, e->timestamp);
  27.     }
  28.     break;
  29.   case EVENT_CRASH: 
  30.     data = game->player[e->player].data;
  31.     data->posx = data->iposx = e->x;
  32.     data->posy = data->iposy = e->y;
  33.     sprintf(messages, "player %d crashed", e->player + 1);
  34.     fprintf(stderr, "%s\n", messages);
  35.     consoleAddLine(messages);
  36.     crashPlayer(e->player);
  37.     break;
  38.   case EVENT_STOP:
  39.     fprintf(stderr, "game stopped\n");
  40.     if(game2->mode == GAME_SINGLE_RECORD) {
  41.       stopRecording();
  42.       game2->mode = GAME_SINGLE;
  43.     } else if(game2->mode == GAME_PLAY) {
  44.       stopPlaying();
  45.       game2->mode = GAME_SINGLE;
  46.     }
  47.     game->winner = e->player;
  48.     sprintf(messages, "winner: %d", game->winner + 1);
  49.     printf("%s\n", messages);
  50.     consoleAddLine(messages);
  51.     switchCallbacks(&pauseCallbacks);
  52.     /* screenSaverCheck(0); */
  53.     stoptime = SystemGetElapsedTime();
  54.     game->pauseflag = PAUSE_GAME_FINISHED;
  55.     value = 1;
  56.     break;
  57.   }
  58.   free(e);
  59.   return value;
  60. }
  61.  
  62. list* doMovement(int mode, int dt) {
  63.   int i;
  64.   float fs;
  65.   Data *data;
  66.   list *l = NULL;
  67.   GameEvent *e;
  68.  
  69.   for(i = 0; i < game->players; i++) {
  70.     data = game->player[i].data;
  71.     if(data->speed > 0) { /* still alive */
  72.  
  73. #define FREQ 1200
  74. #define FACTOR 0.09
  75.       fs = 1.0 - FACTOR + FACTOR * 
  76.     cos(i * M_PI / 4.0 + 
  77.         (float)(game2->time.current % FREQ) * 2.0 * M_PI / (float)FREQ);
  78. #undef FREQ
  79. #undef FACTOR
  80.  
  81.       data->t += dt / 100.0 * data->speed * fs;
  82.       while(data->t >= 1) {
  83.     moveStep(data);
  84.     data->t--;
  85.     if(getCol(data->iposx, data->iposy) && mode) {
  86.       e = (GameEvent*) malloc(sizeof(GameEvent));
  87.       e->type = EVENT_CRASH;
  88.       e->player = i;
  89.       e->x = data->iposx;
  90.       e->y = data->iposy;
  91.       e->timestamp = game2->time.current;
  92.       addList(&l, e);
  93.       break;
  94.     } else {
  95.       writePosition(i);
  96.     }
  97.       }
  98.       data->posx = data->iposx + data->t * dirsX[data->dir];
  99.       data->posy = data->iposy + data->t * dirsY[data->dir];
  100.     } else { /* already crashed */
  101.       if(game2->rules.eraseCrashed == 1 && data->trail_height > 0)
  102.     data->trail_height -= (float)(dt * TRAIL_HEIGHT) / 1000;
  103.       if(data->exp_radius < EXP_RADIUS_MAX)
  104.     data->exp_radius += (float)dt * EXP_RADIUS_DELTA;
  105.       else if (data->speed == SPEED_CRASHED) {
  106.     int winner = -1;
  107.  
  108.     data->speed = SPEED_GONE;
  109.     game->running--;
  110.     if(game->running <= 1) { /* all dead, find survivor */
  111.       int i, maxSpeed = SPEED_GONE;
  112.       /* create winner event */
  113.       for(i = 0; i < game->players; i++) {
  114.         if(game->player[i].data->speed >= maxSpeed) {
  115.           winner = i;
  116.           maxSpeed = game->player[i].data->speed;
  117.         }
  118.       }
  119.       if(mode) {
  120.         e = (GameEvent*) malloc(sizeof(GameEvent));
  121.         e->type = EVENT_STOP;
  122.         e->player = winner;
  123.         e->timestamp = game2->time.current;
  124.         e->x = 0; e->y = 0;
  125.         addList(&l, e);
  126.         /* a stop event is the last event that happens */
  127.         return l;
  128.       }
  129.     }
  130.       }
  131.     }      
  132.   }
  133.   return l;
  134. }
  135.  
  136.  
  137. void idleGame( void ) {
  138.   list *l;
  139.   list *p;
  140.   int i;
  141.   int dt;
  142.   int t;
  143.  
  144. #ifdef SOUND
  145.   soundIdle();
  146. #endif
  147.  
  148.   if(updateTime() == 0) return;
  149.   switch(game2->mode) {
  150.   case GAME_NETWORK_RECORD:
  151. #ifdef NETWORK
  152.     updateNet();
  153. #endif
  154.     /* fall through */
  155.   case GAME_SINGLE:
  156.   case GAME_SINGLE_RECORD:
  157.     /* check for fast finish */
  158.     if(game->settings->fast_finish == 1) {
  159.       int factor = 4;
  160.       for(i = 0; i < game->players; i++) {
  161.     if(game->player[i].ai->active != 1 &&
  162.        game->player[i].data->exp_radius < EXP_RADIUS_MAX)
  163.       factor = 1;
  164.       }
  165.       dt = game2->time.dt * factor;
  166.     } else  
  167.       dt = game2->time.dt;
  168.  
  169.     while(dt > 0) {
  170.       if(dt > PHYSICS_RATE) t = PHYSICS_RATE;
  171.       else t = dt;
  172.  
  173.       /* run AI */
  174.       for(i = 0; i < game->players; i++)
  175.     if(game->player[i].ai != NULL)
  176.       if(game->player[i].ai->active == 1 &&
  177.          game->player[i].data->speed > 0) {
  178.         if(game->settings->ai_level < 2)
  179.           doComputer(i, 0);
  180.         else 
  181.           doComputer2(i, 0);
  182.       }
  183.  
  184.       /* process any outstanding events (turns, etc) */
  185.       for(p = &(game2->events); p->next != NULL; p = p->next) {
  186.     if(processEvent((GameEvent*) p->data)) return;
  187.       }
  188.  
  189.       /* free events */
  190.       p = game2->events.next;
  191.       while(p != NULL) {
  192.     l = p;
  193.     p = p->next;
  194.     free(l);
  195.       }
  196.       game2->events.next = NULL;
  197.  
  198.       l = doMovement(1, t); /* this can generate new events */
  199.       if(l != NULL) {
  200.     for(p = l; p->next != NULL; p = p->next) {
  201.       if(processEvent((GameEvent*) p->data));
  202.     }
  203.  
  204.       }
  205.       /* free list  */
  206.       p = l;
  207.       while(p != NULL) {
  208.     l = p;
  209.     p = p->next;
  210.     free(l);
  211.       }
  212.       dt -= PHYSICS_RATE;
  213.     }
  214.     break;
  215.   case GAME_PLAY_NETWORK:
  216. #ifdef NETWORK
  217.     updateNet();
  218.     /* broadCast any outstanding events (turns, etc) */
  219.     for(p = &(game2->events); p->next != NULL; p = p->next) {
  220.       sendNetEvent((GameEvent*) p->data);
  221.     }
  222. #endif
  223.     /* fall through to GAME_PLAY */
  224.   case GAME_PLAY:
  225.     getEvents(); 
  226.     l = doMovement(0, game2->time.dt); /* this won't generate new events */
  227.     if(l != NULL) {
  228.       fprintf(stderr, "something is seriously wrong - ignoring events\n");
  229.     }
  230.     break;
  231.   }
  232.     
  233.   camMove();
  234.   chaseCamMove();
  235.  
  236.   SystemPostRedisplay();
  237.   /* fprintf(stderr, "game time: %.3f\n", game2->time.current / 1000.0); */
  238. }
  239.  
  240. /* create an event and put it into the global event queue */
  241.  
  242. void createTurnEvent(int player, int direction) {
  243.   GameEvent *e;
  244.   list *p;
  245.  
  246.   for(p = &(game2->events); p->next != NULL; p = p->next);
  247.   e = (GameEvent*) malloc(sizeof(GameEvent));
  248.   p->data = e;
  249.   p->next = (list*) malloc(sizeof(list));
  250.   p->next->next = NULL;
  251.   switch(direction) {
  252.   case TURN_LEFT: e->type = EVENT_TURN_LEFT; break;
  253.   case TURN_RIGHT: e->type = EVENT_TURN_RIGHT; break;
  254.   }
  255.   e->x = game->player[player].data->iposx;
  256.   e->y = game->player[player].data->iposy;
  257.   e->player = player;
  258.   e->timestamp = game2->time.current;
  259. }
  260.